home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
KISS.C
< prev
next >
Wrap
Text File
|
1993-08-09
|
4KB
|
171 lines
/* Routines for AX.25 encapsulation in KISS TNC
* Copyright 1991 Phil Karn, KA9Q
*/
#include "global.h"
#include "config.h"
#include "mbuf.h"
#include "iface.h"
#include "kiss.h"
#include "slip.h"
#include "asy.h"
#include "ax25.h"
#include "devparam.h"
/* Process incoming KISS TNC frame */
void
kiss_recv(struct iface *iface,struct mbuf *bp)
{
struct iface *kissif;
char kisstype = PULLCHAR(&bp);
int port = kisstype >> 4;
if((kissif = Slip[iface->xdev].kiss[port]) == NULLIF) {
free_p(bp);
return;
}
if((kisstype & 0xf) == PARAM_DATA) {
ax_recv(kissif,bp);
return;
}
free_p(bp);
}
#if defined (KISS) && (defined(ASY) || defined(SCC))
/* Send raw data packet on KISS TNC */
int
kiss_raw(struct iface *iface,struct mbuf *data)
{
/* Put type field for KISS TNC on front */
struct mbuf *bp = pushdown(data,1);
bp->data[0] = (iface->port << 4) | PARAM_DATA;
if(iface->port) {
iface->rawsndcnt++;
iface->lastsent = secclock();
}
/* slip_raw also increments sndrawcnt */
slip_raw(Slip[iface->xdev].iface,bp);
return 0;
}
/* Perform device control on KISS TNC by sending control messages */
int32
kiss_ioctl(struct iface *iface,int cmd,int set,int32 val)
{
struct mbuf *hbp;
char *cp;
/* At present, only certain parameters are supported by
* stock KISS TNCs. As additional params are implemented,
* this will have to be edited
*/
switch(cmd){
case PARAM_RETURN:
case PARAM_RETURN2:
set = 1; /* Note fall-thru */
case PARAM_TXDELAY:
case PARAM_PERSIST:
case PARAM_SLOTTIME:
case PARAM_TXTAIL:
case PARAM_FULLDUP:
case PARAM_HW:
if(!set) {
/* Can't read back */
return -1;
}
/* Allocate space for cmd and arg */
hbp = alloc_mbuf(2);
cp = hbp->data;
*cp++ = cmd;
*cp = val;
hbp->cnt = 2;
if((int)hbp->data[0] != PARAM_RETURN) {
hbp->data[0] |= (iface->port << 4);
}
if(iface->port) {
iface->rawsndcnt++;
iface->lastsent = secclock();
}
/* Even more "raw" than kiss_raw */
slip_raw(Slip[iface->xdev].iface,hbp);
return (val * 10);
case PARAM_SPEED: /* These go to the local asy driver */
case PARAM_DTR:
case PARAM_RTS:
case PARAM_UP:
case PARAM_DOWN:
return asy_ioctl(iface,cmd,set,val);
default: /* Not implemented */
return -1;
}
}
static int
kiss_stop(struct iface *iface,int tmp)
{
Slip[iface->xdev].kiss[iface->port] = NULLIF;
return 0;
}
/* Attach a kiss interface to an existing asy interface in the system
* argv[0]: hardware type, must be "kiss"
* argv[1]: master interface, e.g., "ax4"
* argv[2]: kiss port, e.g., "4"
* argv[3]: interface label, e.g., "ax0"
* argv[4]: maximum transmission unit, bytes
*/
int
kiss_attach(int argc,char **argv,void *p)
{
struct iface *if_asy, *if_kiss;
int port;
static char portmsg[] = "Port %d already allocated on iface %s\n";
if((if_asy = if_lookup(argv[1])) == NULLIF) {
tprintf(Badif,argv[1]);
return -1;
}
if(if_lookup(argv[3]) != NULLIF) {
tprintf(Ifexist,argv[4]);
return -1;
}
if((port = atoi(argv[2])) < 1) {
tprintf(portmsg,0,argv[1]);
return -1;
}
if(port > 15) {
port = 15;
}
if(Slip[if_asy->xdev].kiss[port] != NULLIF) {
tprintf(portmsg,port,argv[1]);
return -1;
}
/* Create interface structure and fill in details */
if_kiss = mxallocw(sizeof(struct iface));
if_kiss->addr = if_asy->addr;
if_kiss->name = strxdup(argv[3]);
if_kiss->mtu = (argc >= 5) ? atoi(argv[4]) : if_asy->mtu;
if_kiss->dev = if_asy->dev;
if_kiss->stop = kiss_stop;
setencap(if_kiss,"AX25");
if_kiss->ioctl = kiss_ioctl;
if_kiss->raw = kiss_raw;
if_kiss->hwaddr = strxdup(Mycall);
if_kiss->xdev = if_asy->xdev;
init_maxheard(if_kiss);
init_flags(if_kiss);
if_kiss->next = Ifaces;
if_kiss->niface = Niface++;
if_kiss->port = port;
Ifaces = if_kiss;
Slip[if_kiss->xdev].kiss[if_kiss->port] = if_kiss;
return 0;
}
#endif /* ax25 + asy | scc */